> >NeXT Object class provides allocFromZone:. I think an allocFromAutomatic >would be an elegant approach. allocFromAutomatic would use alloca() (see >MALLOC(3)) to allocate memory from the stack.
>
> This would solve the problem only in the case of objects that do not have out-of-line storage associated with them. E.g.,
>
> @interface MyString:Object
> {
> char *theBuffer;
> }
> @end
>
> would end up leaving whatever "theBuffer" points to unfreed on function return.
>
> The "problem" with automatic object allocation is that it introduces the need for constructor & destructor syntax/semantics.
>
> Andrew Athan
> Objective Technologies, Inc.
>
I, personally, am going on the assumption that, on exit from the stack frame, all of your automatic objects would be sent -free.
All that this requires to work is that -free deallocates any allocated memory, which it's supposed to do anyway. You can do without writing a -free method, in which case you're open to memory leaks.
- Kurt
Kurt Starsinic # kstar@medequity.com
Director of Systems # (NeXTmail preferred)
MedEquity, Inc. #
555 North Lane, Suite 6183 # (215) 397-0201 voice
Conshohocken, PA 19428 # 397-0203 fax
The opinions expressed by me just might be those of MedEquity, Inc.
"What we think, or what we know, or what we believe is, in the end,
of little consequence. The only consequence is what we do."
- John Rushin
Return-Path: <burchard@geom.umn.edu>
Date: Mon, 22 Feb 93 17:59:19 -0600
From: burchard@geom.umn.edu
To: gnu-objc@gnu.ai.mit.edu
Subject: Cleanup of basic Obj-C memory management protocol
I would like to propose some very slight and simple changes to the
basic memory management methods of the Object class in the GNU Obj-C
runtime. These changes will make the GNU runtime MORE compatible
with both NeXT and Stepstone; moreover, they will enable cleaner
subclassing of these basic operations.
These changes are very simple and complete source code is given
below.
The basic principle is to allow memory allocation and initialization
to be performed by separate methods. This is necessary for proper
subclassing, because the object which is performing the allocation is
NOT the same as the one which is subsequently initialized!
NeXT has already made this split for +new. I propose to do the same
with -copy, which is currently a bit ugly to subclass. Thus, in the
Object class, there should be two analogous divisions of labor:
(+new) = (+alloc) + (-init)
(-copy) = (-shallowCopy) + (-deep)
Note that this is completely compatible with "old style" code---both
+new and -copy may still be overridden directly, by software that
assumes they are the basic runtime methods, without any adverse
effect.
However, savvy programs will almost always override only -init and
-deep, which provide a cleaner way for subclasses to modify these
operations. To be absolutely clear, let me spell out what each
method's responsibility is:
-copy
This method should "do the right thing" for each class, to
produce a working copy of the object.
One problem encountered by this method is that after a
shallow copy of the receiver is made, the remaining
operations take place in the new object, not the one being
copied. In order for this to work well with subclassing,
there needs to be a separate, subclassable method to handle
the operations which "deepen" the copy. This is the purpose
of the -deep method below. The only job of -copy is to
allocate a new shallow copy and then call -deep on it.
The Object class should define this method as a combination
of -shallowCopy and -deep. This does not conflict with
existing classes on the NeXT, which don't define -deep.
-deep
This method allows subclasses to extend the way in which a
copy is deepened. It is normally not necessary to override
the -copy method at all (unless you really want to change
the allocation procedures).
For example:
@implementation MyClass : MySuperclass
{
int *thang;
int thangSize;
}
- deep
{
int *oldThang;
if(![super deep]) return nil;
oldThang = thang;
if(!MALLOC(thang, int, thangSize))
{ [self free]; return nil; }
bcopy(oldThang, thang, thangSize*sizeof(int));
return self;
}
-shallowCopy
This method is simply a wrapper for object_copy(), and should
not be overridden. It allocates space for a new object and
fills that space with an exact binary duplicate of the
receiver's direct instance variables.
###-deepCopy###
This method should not really exist, except for compatibility
with Stepstone's Obj-C. If this method doesn't perform the
same operation as -copy, described above, it's probably
the wrong thing to do.
The +new, +alloc, and -init methods have been already described well
by NeXT, so I won't repeat that. Here is the complete source code:
---------------------- changes to Object.m ----------------------
- copy
{
return [[self shallowCopy] deep];
}
- shallowCopy
{
return object_copy(self);
}
- deep
{
// Subclasses extend this.
return self;
}
- deepCopy
{
// For Stepstone compatibility only.
// Does not actually guarantee literal "deep copy".
Subject: Cleanup of basic Obj-C memory management protocol
> From: Timothy J. Wood <uunet!omnigroup.com!bungi>
>
> Some thoughts about memory management and -copy/-deepCopy... Say we have:
>
> @interface Blorf : Object
> {
> id blegga;
> }
> @end
>
>
> Then if
>
> aBlorf = [[Blorf alloc] init];
> ...
> copyOfBlorf = [aBlorf copy];
> ...
> [copyOfBlorf free];
>
>
> we need to resolve the question of ownership of blegga. Does aBlorf or
> copyOfBlorf own it? Obviously the compiler can't resolve this question
> for us; the programmer must do so.
(I believe that I'm about to agree w/ what Paul B said)
PB > I don't think standardization would be helpful since there are a whole
PB > variety of memory management schemes that you might want to implement for
PB > various classes; the standard one and copy-on-write are just two. There's
PB > also reference counting and recycling, for example. Not to mention real
PB > garbage collection (dreaming...).
I think it must be determined on a class by class basis.
And copy should be implemented in a many that would allow the returned
instance to be freed. To force a programmer into on pigeon hole
when he may want another is not good. He may want his copy to up the
reference count in the instance variable, or create a new one. Who's
to say which is better? (A: the programmer is, not the language implementer)
> One obvious solution is to have two types of -free (called -free and
> -shallowFree), just as we have two types of copy. For this class they might
> be implemented something like this:
>
> - free { [blegga free]; return [super free]; }
> - shallowFree { return [super free]; }
>
> (The reason for not naming them -free and -deepFree is that existing code
> assumes -free == -deepFree)
>
> An alternative approach would be to implement reference counting of
> objects in the Object class and have -copy increment the ref count of the
> instance variable objects in the copied object while -deepCopy would just
> make new instances with a refCount of one. -free could then decrement the
> refCount and the really free the object if the refCount hits zero.
>
> I guess what I am proposing is that one or the other (or some other) approach
> to handling this sort of thing is standardized in the GNU ObjC
> runtime/class hierarchy. This is something that NeXT has sadly neglected
> in their implementation.
>
>
> Timothy J. Wood
> The Omni Group
>
>
>
>
-Bill Shirley
Date: Sat, 27 Feb 93 21:48:11 -0600
From: burchard@geom.umn.edu
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Cleanup of basic Obj-C memory management protocol
Cc: Steve_Naroff@NeXT.COM
I just wanted to let folks know that (thanks to advice from Linus) I changed the name of the message -deep to -deepen in the actual submission I made to GNU. The name -deepen has the advantage of being a verb, and it also more clearly describes the purpose of the message. Thus, the default -copy in Object is implemented as